﻿using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace DetectApp.Display;

public class CloseCurveControl : ROIControl
{
    private readonly Canvas _canvas;

    public double K { get => _canvas.ActualWidth / 500.0; }

    private bool _isMove;
    private readonly List<Shape> _docEllipse = new();

    private Point _startPoint;

    private double _startTopLeft;
    private double _startTopUp;
    private PolyLineSegment _polyLineSegment;
    private PathFigure _curPathFigure;
    private Path _CurPath;
    private bool IsStartDraw;

    public CloseCurveControl(Canvas canvas, Color color)
    {
        _canvas = canvas;
        _polyLineSegment = new() { };
        _curPathFigure = new();
        _curPathFigure.Segments.Add(_polyLineSegment);
        PathGeometry pathGeometry1 = new();
        pathGeometry1.Figures.Add(_curPathFigure);
        _CurPath = new()
        {
            Stroke = new SolidColorBrush(color),
            Data = pathGeometry1,

            Fill = new SolidColorBrush(Colors.Red) { Opacity = 0.1 },
            StrokeThickness = 0.1,
        };
        _canvas.MouseLeftButtonDown += CurPath_MouseLeftButtonDown;
        _canvas.MouseMove += Canvas_MouseMove;
        _canvas.Children.Add(_CurPath);
        IsStartDraw = true;
        _canvas.Background = new SolidColorBrush(new Color() { A = 20, R = 255, G = 0, B = 0 });
        ROIChange?.Invoke(this, EventArgs.Empty);
    }

    public CloseCurveControl(Canvas canvas, ROIParam param)
    {
        _canvas = canvas;
        _polyLineSegment = new() { Points = new PointCollection(param.close_points) };
        _curPathFigure = new() { StartPoint = param.close_start, IsClosed = true };
        _curPathFigure.Segments.Add(_polyLineSegment);
        PathGeometry pathGeometry1 = new();
        pathGeometry1.Figures.Add(_curPathFigure);
        _CurPath = new()
        {
            Stroke = new SolidColorBrush(Colors.Blue),
            Data = pathGeometry1,

            Fill = new SolidColorBrush(Colors.Red) { Opacity = 0.1 },
            StrokeThickness = 0.1,
        };
        _canvas.MouseLeftButtonDown += CurPath_MouseLeftButtonDown;
        _canvas.MouseMove += Canvas_MouseMove;
        Canvas.SetLeft(_CurPath, param.Left);
        Canvas.SetTop(_CurPath, param.Top);
        _canvas.Children.Add(_CurPath);
        ROIChange?.Invoke(this, EventArgs.Empty);
    }

    private bool IsDraw;

    private void CurPath_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (IsStartDraw)
        {
            IsDraw = true;
            _curPathFigure.StartPoint = Mouse.GetPosition(_canvas);
            Canvas.SetTop(_CurPath, 0);
            Canvas.SetLeft(_CurPath, 0);
        }
        else if (_CurPath.IsMouseOver && !IsDraw)
        {
            _isMove = true;
            _startPoint = Mouse.GetPosition(_canvas);
            _startTopUp = Canvas.GetTop(_CurPath);
            _startTopLeft = Canvas.GetLeft(_CurPath);
        }
    }

    private bool IsOld = false;

    private void Canvas_MouseMove(object sender, MouseEventArgs e)
    {
        if (Mouse.LeftButton == MouseButtonState.Released)
        {
            _isMove = false;
            IsDraw = false;
        }
        if (IsOld & !IsDraw)
        {
            _curPathFigure.IsClosed = true;
            _canvas.Background = new SolidColorBrush(Colors.Transparent);
            ROIChange?.Invoke(this, EventArgs.Empty);
        }
        if (_isMove)
        {
            Point curPoint = Mouse.GetPosition(_canvas);
            var rPoint = curPoint - _startPoint;
            Canvas.SetLeft(_CurPath, _startTopLeft + rPoint.X);
            Canvas.SetTop(_CurPath, _startTopUp + rPoint.Y);
            ROIChange?.Invoke(this, EventArgs.Empty);
        }
        if (IsDraw)
        {
            IsOld = true;
            _canvas.Background = new SolidColorBrush(new Color() { A = 20, R = 255, G = 0, B = 0 });
            _polyLineSegment.Points.Add(Mouse.GetPosition(_canvas));
            IsStartDraw = false;
        }
        else IsOld = false;
    }

    public override HRegion? GetRegion()
    {
        HRegion region = new();

        HTuple rows = _polyLineSegment.Points.Select(p => _CurPath.TranslatePoint(p, _canvas).Y).ToArray();
        HTuple cols = _polyLineSegment.Points.Select(p => _CurPath.TranslatePoint(p, _canvas).X).ToArray();
        region.GenRegionPolygonFilled(rows, cols);
        return region;
    }

    public override ROIInfo GetROI()
    {
        return new ROIInfo() { ROIType = ROIType.无 };
    }

    public override ROIParam GetParam()
    {
        ROIParam param = new() { ROIType = ROIType.封闭曲线 };
        param.close_start = _curPathFigure.StartPoint;
        param.close_points = _polyLineSegment.Points.ToList();
        return param;
    }

    public override void Remove()
    {
        _canvas.Children.Remove(_CurPath);
    }
}